﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace YouTubeStormer
{
    public partial class ConfigForm : Form
    {
        public bool AccountProxyBindsChanged = false;

        Timer commentGenerator = new Timer();
        YouTubeScraper.Scraper scraper = new YouTubeScraper.Scraper();

        public ConfigForm()
        {
            InitializeComponent();
            Icon = Properties.Resources.configureIcon;
            VisibleChanged += ConfigForm_VisibleChanged;
            FormClosing += ConfigForm_FormClosing;

            scraper.VideosAdded += new YouTubeScraper.Scraper.VideosAddedHandler(scraper_VideosAdded);

            commentGenerator.Interval = 3000;
            commentGenerator.Tick += commentGenerator_Tick;
            commentGenerator.Start();
        }

        void scraper_VideosAdded(Dictionary<string, string> videos)
        {
            foreach (KeyValuePair<string, string> pair in videos)
            {
                foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    if (row.Cells[0].Value as string == pair.Key) goto FINISHED;
                }

                var newRow = new DataGridViewRow();
                newRow.CreateCells(dataGridView1);
                try
                {
                    newRow.Cells[0].Value = pair.Key;
                    newRow.Cells[2].Value = pair.Value;
                    dataGridView1.Rows.Add(newRow);
                }
                catch { }
            FINISHED:
                continue;
            }
        }

        void commentGenerator_Tick(object sender, EventArgs e)
        {
            labelPossibleCombos.Text = (Configuration.GetPossibleCommentCombos() + " Possible Combos");
            textBoxExample.Text = Configuration.GenerateComment("{TAG}");
        }

        void ConfigForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            Hide();
        }

        void ConfigForm_VisibleChanged(object sender, EventArgs e)
        {
            if (Visible) LoadConfig();
        }

        void IncrementParts()
        {
            commentParts.ColumnCount++;
            UpdateCommentParts();
        }

        void DecrementParts()
        {
            commentParts.ColumnCount--;
            UpdateCommentParts();
        }

        void UpdateCommentParts()
        {
            float columnWidthPercent = (float)(100 / commentParts.ColumnCount);

            for (int i = 0; i < commentParts.ColumnCount; i++)
            {
                var columnStyle = new ColumnStyle(System.Windows.Forms.SizeType.Percent, columnWidthPercent);
                if (commentParts.ColumnStyles.Count > i) commentParts.ColumnStyles[i] = columnStyle;
                else commentParts.ColumnStyles.Add(columnStyle);

                if (commentParts.Controls.Count > commentParts.ColumnCount)
                {
                    commentParts.Controls.RemoveAt(commentParts.Controls.Count - 1);
                }
                else if (commentParts.Controls.Count < commentParts.ColumnCount)
                {
                    commentParts.Controls.Add(new RichTextBox { Dock = DockStyle.Fill, BorderStyle = BorderStyle.None, WordWrap = false }, commentParts.Controls.Count, 0);
                }
            }

            buttonDecrementParts.Enabled = commentParts.ColumnCount > 1;
        }

        private void buttonIncrementParts_Click(object sender, EventArgs e)
        {
            IncrementParts();
        }

        private void buttonDecrementParts_Click(object sender, EventArgs e)
        {
            DecrementParts();
        }

        void SaveVideoInfo()
        {
            List<string> videoInfoLines = new List<string>();
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                List<string> lineParts = new List<string>();
                if (row.Cells[0].Value != null)
                {
                    if (row.Cells[0].Value.ToString() != "") lineParts.Add(row.Cells[0].Value.ToString());
                    else continue;
                    if (row.Cells[1].Value != null) lineParts.Add(row.Cells[1].Value.ToString());
                    else lineParts.Add("");
                    if (row.Cells[2].Value != null) lineParts.Add(row.Cells[2].Value.ToString());
                    else lineParts.Add("");

                    videoInfoLines.Add(string.Join(Configuration.VideoInfoSplitter, lineParts.ToArray()));
                }
                
            }

            Properties.Settings.Default.Videos.Clear();
            Properties.Settings.Default.Videos.AddRange(videoInfoLines.Distinct().ToArray());
        }

        void LoadVideoInfo()
        {
            dataGridView1.Rows.Clear();
            foreach (string videoInfoLine in Configuration.StringCollectionToArray(Properties.Settings.Default.Videos))
            {
                var row = new DataGridViewRow();
                row.CreateCells(dataGridView1);
                var lineInfoParts = Regex.Split(videoInfoLine, Configuration.VideoInfoSplitter);
                try
                {
                    row.Cells[0].Value = lineInfoParts[0];
                    if (lineInfoParts.Length > 0) row.Cells[1].Value = lineInfoParts[1];
                    if (lineInfoParts.Length > 1) row.Cells[2].Value = lineInfoParts[2];
                }
                catch { }
                dataGridView1.Rows.Add(row);
            }
        }

        void SaveConfig()
        {
            if (string.Join("", richTextBoxAccounts.Lines) != string.Join("", Configuration.StringCollectionToArray(Properties.Settings.Default.Accounts, false)))
                AccountProxyBindsChanged = true;
            else 
                AccountProxyBindsChanged = false;


            Properties.Settings.Default.Accounts.Clear();
            Properties.Settings.Default.Accounts.AddRange(richTextBoxAccounts.Lines.Distinct().ToArray());

            SaveVideoInfo();

            Properties.Settings.Default.Links.Clear();
            Properties.Settings.Default.Links.AddRange(richTextBoxLinks.Lines);

            Properties.Settings.Default.DeathByCaptchaUsername = textBoxUsername.Text;
            Properties.Settings.Default.DeathByCaptchaPassword = textBoxPassword.Text;

            Properties.Settings.Default.CommentParts.Clear();
            for(int i = 0; i < commentParts.Controls.Count; i++)
            {
                Properties.Settings.Default.CommentParts.Add(commentParts.Controls[i].Text);
            }

            Properties.Settings.Default.Save();
        }

        void LoadConfig()
        {
            AccountProxyBindsChanged = false;

            richTextBoxAccounts.Text = string.Join(Environment.NewLine, Configuration.StringCollectionToArray(Properties.Settings.Default.Accounts));

            LoadVideoInfo();

            richTextBoxLinks.Text = string.Join(Environment.NewLine, Configuration.StringCollectionToArray(Properties.Settings.Default.Links));

            textBoxUsername.Text = Properties.Settings.Default.DeathByCaptchaUsername;
            textBoxPassword.Text = Properties.Settings.Default.DeathByCaptchaPassword;

            commentParts.ColumnCount = Properties.Settings.Default.CommentParts.Count;
            UpdateCommentParts();
            for (int i = 0; i < Properties.Settings.Default.CommentParts.Count; i++)
            {
                commentParts.Controls[i].Text = Properties.Settings.Default.CommentParts[i];
            }
        }

        private void buttonSave_Click(object sender, EventArgs e)
        {
            SaveConfig();
            Hide();
        }

        private void buttonApply_Click(object sender, EventArgs e)
        {
            SaveConfig();
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            Hide();
        }

        private void buttonScraper_Click(object sender, EventArgs e)
        {
            scraper.Show();
        }

        private void buttonClear_Click(object sender, EventArgs e)
        {
            dataGridView1.Rows.Clear();
        }

        public class ClipboardUtils
        {
            public static void OnDataGridViewPaste(object grid, KeyEventArgs e)
            {
                if ((e.Shift && e.KeyCode == Keys.Insert) || (e.Control && e.KeyCode == Keys.V))
                {
                    PasteTSV((DataGridView)grid);
                }
            }

            public static void PasteTSV(DataGridView grid)
            {
                char[] rowSplitter = { '\r', '\n' };
                char[] columnSplitter = { '\t' };

                IDataObject dataInClipboard = Clipboard.GetDataObject();
                string stringInClipboard = (string)dataInClipboard.GetData(DataFormats.Text);

                string[] rowsInClipboard = stringInClipboard.Split(rowSplitter, StringSplitOptions.RemoveEmptyEntries);

                int r = grid.SelectedCells[0].RowIndex;
                int c = grid.SelectedCells[0].ColumnIndex;

                if (grid.Rows.Count < (r + rowsInClipboard.Length))
                    grid.Rows.Add(r + rowsInClipboard.Length - grid.Rows.Count);

                for (int iRow = 0; iRow < rowsInClipboard.Length; iRow++)
                {
                    string[] valuesInRow = rowsInClipboard[iRow].Split(columnSplitter);

                    for (int iCol = 0; iCol < valuesInRow.Length; iCol++)
                    {
                        if (grid.ColumnCount - 1 >= c + iCol)
                        {
                            DataGridViewCell cell = grid.Rows[r + iRow].Cells[c + iCol];
                            if (!cell.ReadOnly)
                                cell.Value = valuesInRow[iCol];
                        }
                    }
                }
            }
        }

        private void dataGridView1_KeyUp(object sender, KeyEventArgs e)
        {
            ClipboardUtils.OnDataGridViewPaste(sender, e);
        }

    }
}
